// author: enic
// date: 2015-02-24

#pragma once

#include "import_stdlib.h"

class CallOnScopeExit
{
public:
	explicit CallOnScopeExit(std::function<void()> onExit)
		: m_OnExitScope(onExit),
		m_bDismissed(false)
	{

	}

	~CallOnScopeExit()
	{
		if (!m_bDismissed)
		{
			if (m_OnExitScope)
			{
				m_OnExitScope();
			}
		}
	}

	void Dismiss()
	{
		m_bDismissed = true;
	}

private:
	std::function<void()> m_OnExitScope;
	bool m_bDismissed;
};

#define CALL_ON_SCOPE_EXIT_LINENAME_CAT(name, line) name##line 
#define CALL_ON_SCOPE_EXIT_LINENAME(name, line)  \
	CALL_ON_SCOPE_EXIT_LINENAME_CAT(name, line) 

#define CALL_ON_SCOPE_EXIT(callback)  \
	CallOnScopeExit CALL_ON_SCOPE_EXIT_LINENAME(EXIT, __LINE__)(callback) 